home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks95 / Aaron 1.0b3.sit / Aaron 1.0b3 / Aaron Source / ShowInitIcon 1.0 / ShowInitIcon.c next >
Text File  |  1995-06-24  |  6KB  |  158 lines

  1. // ShowInitIcon - version 1.0, May 11th, 1995
  2. // This code is intended to let INIT writers easily display an icon at startup time.
  3. // View in Geneva 9pt, 4-space tabs
  4.  
  5. // Written by: Peter N Lewis <peter@mail.peter.com.au>, Jim Walker <JWWalker@aol.com>
  6. // and François Pottier <pottier@dmi.ens.fr>, with thanks to previous ShowINIT authors.
  7. // Send comments and bug reports to François Pottier.
  8.  
  9. // This version features:
  10. // - Short and readable code.
  11. // - Correctly wraps around when more than one row of icons has been displayed.
  12. // - works with System 6
  13. // - Built with Universal Headers & CodeWarrior. Should work with other headers/compilers.
  14.  
  15. #include "ShowInitIcon.h"
  16. #include <Resources.h>
  17. #include <Icons.h>
  18. #include <OSUtils.h>
  19.  
  20. // You should set SystemSixOrLater in your headers to avoid including glue for SysEnvirons.
  21.  
  22. // ---------------------------------------------------------------------------------------------------------------------
  23. // Set this flag to 1 if you want to compile this file into a stand-alone resource (see note below).
  24. // Set it to 0 if you want to include this source file into your INIT project.
  25.  
  26. #if 0
  27. #define ShowInitIcon main
  28. #endif
  29.  
  30. // ---------------------------------------------------------------------------------------------------------------------
  31. // The ShowINIT mechanism works by having each INIT read/write data from these globals.
  32.  
  33. extern short LMVCoord:        0x92A;
  34. extern short LMVCheckSum:    0x928;
  35. extern short LMHCoord:        0x092C;
  36. extern short LMHCheckSum:    0x092E;
  37.  
  38. // ---------------------------------------------------------------------------------------------------------------------
  39. // Prototypes for the subroutines. The main routine comes first; this is necessary to make THINK C's "Custom Header" option work.
  40.  
  41. static unsigned short CheckSum (unsigned short x);
  42. static void ComputeIconRect (Rect* iconRect, Rect* screenBounds);
  43. static void AdvanceIconPosition (Rect* iconRect);
  44. static void DrawBWIcon (short iconID, Rect *iconRect);
  45.  
  46. // ---------------------------------------------------------------------------------------------------------------------
  47. // Main routine.
  48.  
  49. typedef struct {
  50.     QDGlobals            qd;                                    // Storage for the QuickDraw globals
  51.     long                qdGlobalsPtr;                            // A5 points to this place; it will contain a pointer to qd
  52. } QDStorage;
  53.  
  54. pascal void ShowInitIcon (short iconFamilyID, Boolean advance)
  55. {
  56.     long                oldA5;                                // Original value of register A5
  57.     QDStorage            qds;                                    // Fake QD globals
  58.     CGrafPort            colorPort;
  59.     GrafPort            bwPort;
  60.     Rect                destRect;
  61.     SysEnvRec        environment;                            // Machine configuration.
  62.     
  63.     oldA5 = SetA5((long) &qds.qdGlobalsPtr);                        // Tell A5 to point to the end of the fake QD Globals
  64.     InitGraf(&qds.qd.thePort);                                // Initialize the fake QD Globals
  65.     
  66.     SysEnvirons(curSysEnvVers, &environment);                    // Find out what kind of machine this is
  67.  
  68.     ComputeIconRect(&destRect, &qds.qd.screenBits.bounds);            // Compute where the icon should be drawn
  69.  
  70.     if (environment.systemVersion >= 0x0700 && environment.hasColorQD) {
  71.         OpenCPort(&colorPort);
  72.         PlotIconID(&destRect, atNone, ttNone, iconFamilyID);
  73.         CloseCPort(&colorPort);
  74.     }
  75.     else {
  76.         OpenPort(&bwPort);
  77.         DrawBWIcon(iconFamilyID, &destRect);
  78.         ClosePort(&bwPort);
  79.     }
  80.     
  81.     if (advance)
  82.         AdvanceIconPosition (&destRect);
  83.         
  84.     SetA5(oldA5);                                             // Restore A5 to its previous value
  85. }
  86.  
  87. // ---------------------------------------------------------------------------------------------------------------------
  88. // A checksum is used to make sure that the data in there was left by another ShowINIT-aware INIT.
  89.  
  90. static unsigned short CheckSum (unsigned short x)
  91. {
  92.     return ((x << 1) | (x >> 15)) ^ 0x1021;
  93. }
  94.  
  95. // ---------------------------------------------------------------------------------------------------------------------
  96. // ComputeIconRect computes where the icon should be displayed.
  97.  
  98. static void ComputeIconRect (Rect* iconRect, Rect* screenBounds)
  99. {
  100.     if (CheckSum(LMHCoord) != LMHCheckSum)                    // If we are first, we need to initialize the shared data.
  101.         LMHCoord = 8;
  102.     if (CheckSum(LMVCoord) != LMVCheckSum)
  103.         LMVCoord = screenBounds->bottom - 40;
  104.     
  105.     if (LMHCoord + 34 > screenBounds->right) {                    // Check whether we must wrap
  106.         iconRect->left = 8;
  107.         iconRect->top = LMVCoord - 40;
  108.     }
  109.     else {
  110.         iconRect->left = LMHCoord;
  111.         iconRect->top = LMVCoord;
  112.     }
  113.     iconRect->right = iconRect->left + 32;
  114.     iconRect->bottom = iconRect->top + 32;
  115. }
  116.  
  117. // AdvanceIconPosition updates the shared global variables so that the next extension will draw its icon beside ours.
  118.  
  119. static void AdvanceIconPosition (Rect* iconRect)
  120. {
  121.     LMHCoord = iconRect->left + 40;                            // Update the shared data
  122.     LMVCoord = iconRect->top;
  123.     LMHCheckSum = CheckSum(LMHCoord);
  124.     LMVCheckSum = CheckSum(LMVCoord);
  125. }
  126.  
  127. // DrawBWIcon draws the 'ICN#' member of the icon family. It works under System 6.
  128.  
  129. static void DrawBWIcon (short iconID, Rect *iconRect)
  130. {
  131.     Handle        icon;
  132.     BitMap        source, destination;
  133.     GrafPtr        port;
  134.     
  135.     icon = Get1Resource('ICN#', iconID);
  136.     if (icon) {
  137.         HLock(icon);
  138.                                                         // Prepare the source and destination bitmaps.
  139.         source.baseAddr = *icon + 128;                        // Mask address.
  140.         source.rowBytes = 4;
  141.         SetRect(&source.bounds, 0, 0, 32, 32);
  142.         GetPort(&port);
  143.         destination = port->portBits;
  144.                                                         // Transfer the mask.
  145.         CopyBits(&source, &destination, &source.bounds, iconRect, srcBic, nil);
  146.                                                         // Then the icon.
  147.         source.baseAddr = *icon;
  148.         CopyBits(&source, &destination, &source.bounds, iconRect, srcOr, nil);
  149.     }
  150. }
  151.  
  152. // ---------------------------------------------------------------------------------------------------------------------
  153. // Notes
  154.  
  155. // Checking for PlotIconID:
  156. // We (PNL) now check for system 7 and colour QD, and use colour graf ports and PlotIconID only if both are true
  157. // Otherwise we use B&W grafport and draw using PlotBWIcon.
  158.